/*
 * JFrame.java
 *
 * Created on December 1, 2007, 4:45 PM
 */

/**
 *
 * @author  Brian
 */
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.net.*;
import java.util.*;
public class JFrame extends javax.swing.JFrame {
    String versionInfo = "v1.2.1";
    Socket kkSocket = null;
    PrintWriter out = null;
    BufferedReader in = null;
    ClientHelper ch;
    boolean connected = false;
    protected ArrayList clients; //clients have name:status
    protected ArrayList clientStatus;
    String myStatus = "";
    boolean canType = true;
    /** Creates new form JFrame */
    public String getFirstLine(String file,String backup){
        try{
            FileInputStream fstream = new FileInputStream("config/"+file);
            DataInputStream in2 = new DataInputStream(fstream);
            BufferedReader br2 = new BufferedReader(new InputStreamReader(in2));
            String strLine;
            while ((strLine = br2.readLine()) != null){
                if (strLine != ""){
                    in2.close();
                    return strLine;
                }
            }
        }catch (Exception e){}
        return backup;
    }
    public JFrame() {
        clients = new ArrayList();
        clientStatus = new ArrayList();
        try {
            javax.swing.UIManager.setLookAndFeel(javax.swing.UIManager.getSystemLookAndFeelClassName());          
        }
        catch (Exception e) {
            System.out.println(e);
        } 
        initComponents();

        jTextArea1.append("Welcome. To connect to a server enter the IP address into the textfield, then enter your name in the name box and hit send. Written by Brian Dawn Copyright 2008.");
        jTextField1.setText(getFirstLine("defaultIP.txt",""));
        jTextField2.setText(getFirstLine("defaultName.txt","Your Name Here"));
        paintListener pl = new paintListener();
        
        //Font f = new Font("airel", Font.PLAIN, 12);
        //jTextArea1.setFont(f);
        //jTextArea1.setWrapStyleWord(true);
        setTitle("CHARLES Client "+versionInfo);
    }
    public void initConnection(String IP, String name){
        ch = new ClientHelper(IP, name);
        Thread t = new Thread(ch);
        t.start();
    }
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        jTextField1 = new javax.swing.JTextField();
        jScrollPane2 = new javax.swing.JScrollPane();
        jList1 = new javax.swing.JList();
        jButton1 = new javax.swing.JButton();
        drawingPanel21 = new DrawingPanel2();
        jTextField2 = new javax.swing.JTextField();
        jScrollPane1 = new javax.swing.JScrollPane();
        jTextArea1 = new AppendingTextPane();
        jTextField3 = new javax.swing.JTextField();
        jMenuBar1 = new javax.swing.JMenuBar();
        jMenu1 = new javax.swing.JMenu();
        jMenuItem1 = new javax.swing.JMenuItem();
        jMenu3 = new javax.swing.JMenu();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jTextField1.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                jTextField1KeyPressed(evt);
            }
        });

        jList1.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jList1MouseClicked(evt);
            }
        });
        jScrollPane2.setViewportView(jList1);

        jButton1.setText("Send");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        drawingPanel21.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));

        javax.swing.GroupLayout drawingPanel21Layout = new javax.swing.GroupLayout(drawingPanel21);
        drawingPanel21.setLayout(drawingPanel21Layout);
        drawingPanel21Layout.setHorizontalGroup(
            drawingPanel21Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 759, Short.MAX_VALUE)
        );
        drawingPanel21Layout.setVerticalGroup(
            drawingPanel21Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 219, Short.MAX_VALUE)
        );

        jTextArea1.setEditable(false);
        jTextArea1.setFont(new java.awt.Font("Arial", 0, 12));
        jScrollPane1.setViewportView(jTextArea1);

        jTextField3.setText("green");
        jTextField3.setToolTipText("Font color.");

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(drawingPanel21, javax.swing.GroupLayout.DEFAULT_SIZE, 761, Short.MAX_VALUE)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                .addComponent(jTextField3, javax.swing.GroupLayout.PREFERRED_SIZE, 41, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jTextField1, javax.swing.GroupLayout.DEFAULT_SIZE, 527, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jButton1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jTextField2, javax.swing.GroupLayout.PREFERRED_SIZE, 114, javax.swing.GroupLayout.PREFERRED_SIZE))
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 639, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 116, javax.swing.GroupLayout.PREFERRED_SIZE))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 193, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jScrollPane2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 193, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jButton1)
                    .addComponent(jTextField2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jTextField3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(drawingPanel21, javax.swing.GroupLayout.DEFAULT_SIZE, 221, Short.MAX_VALUE))
        );

        jMenu1.setText("File");

        jMenuItem1.setText("Quit");
        jMenuItem1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem1ActionPerformed(evt);
            }
        });
        jMenu1.add(jMenuItem1);

        jMenuBar1.add(jMenu1);

        jMenu3.setText("About");
        jMenuBar1.add(jMenu3);

        setJMenuBar(jMenuBar1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jMenuItem1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem1ActionPerformed
        System.exit(-1);
    }//GEN-LAST:event_jMenuItem1ActionPerformed

    private void jTextField1KeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_jTextField1KeyPressed
        //if (evt.getKeyCode() == 10){
        //    handleConnect();
        //}
        int typing = 0;
        boolean notSent = true;

        if(jTextField1.getText().length() > 2) notSent = false; //already sent
        if(jTextField1.getText().length() == 0) notSent = false;
        if(jTextField1.getText().length() == 1) notSent = true;
        myStatus = "";
        if(jTextField1.getText().length() > 0){
            if(jTextField1.getText().length() > 1){
                myStatus = "Typing.";
                typing = 1;
            }
        }
        if (evt.getKeyCode() == 10){
            myStatus = "";
            typing = 0;
            handleConnect();
            notSent = true;
        }
        if (notSent == true) out.println("typ*"+typing);

    }//GEN-LAST:event_jTextField1KeyPressed
    private void handleConnect(){
        if(jTextField2.getText().equals("Your Name Here")){
            jTextArea1.append("You must enter a name.");
            //jTextArea1.setCaretPosition(jTextArea1.getText().length());
        }else{
            if(connected == true){
                if(jTextField1.getText().equals("")){
                }else{
                    if(canType == true){
                        String addBegin = "<font color="+jTextField3.getText()+">";
                        String st = jTextField1.getText();
                        if (st.substring(0,1).equals("/")){
                            addBegin = "";
                        }
                        out.println(addBegin+jTextField1.getText());
                        jTextField1.setText("");
                    }
                }
            }else{
                initConnection(jTextField1.getText(), jTextField2.getText());
                jTextField1.setText(""); jTextField2.setEditable(false);
                connected=true;
            }
        }
    }
    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
        handleConnect();
    }//GEN-LAST:event_jButton1ActionPerformed

    private void jList1MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jList1MouseClicked

    }//GEN-LAST:event_jList1MouseClicked
    
    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new JFrame().setVisible(true);
            }
        });
    }
    public void updateStatus(String nameIn, int typing){
        int index = clients.indexOf(nameIn);

        if(typing == 1){
            clientStatus.set(index,"Typing.");
        }else{
            clientStatus.set(index,"");
        }
        String theList = ""; //UPDATE LIST
        for (int i=0; i<clients.size(); i++) {
            String status = (String)clientStatus.get(i);
            if (status != "") status = " -"+status;
            String data = (String)clients.get(i);
            theList += ":"+data+status;
        }
        jList1.setListData(theList.split(":"));           
    }
    public void addToClientList(String added){
        clientStatus.add("");
        clients.add(added);
        //clients.add(""); //WORK ON add and remove
        String theList = "";
        for (int i=0; i<clients.size(); i++) {
            String status = (String)clientStatus.get(i);
            if (status != "") status = " -"+status;
            String data = (String)clients.get(i);
            theList += ":"+data+status;
        }
        jList1.setListData(theList.split(":"));
    }
    public void removeClient(String name){
        int index = clients.indexOf(name); //get the index
        clientStatus.remove(index);
        clients.remove(name);
        String status = "";
        String theList = "";
        for (int i=0; i<clients.size(); i++) {
            String data = (String)clients.get(i);
            status = (String)clientStatus.get(i);
            if (status != "") status = " -"+status;
            theList += ":"+data+status;
        }
        jList1.setListData(theList.split(":"));
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private DrawingPanel2 drawingPanel21;
    private javax.swing.JButton jButton1;
    private javax.swing.JList jList1;
    private javax.swing.JMenu jMenu1;
    private javax.swing.JMenu jMenu3;
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JMenuItem jMenuItem1;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private AppendingTextPane jTextArea1;
    private javax.swing.JTextField jTextField1;
    private javax.swing.JTextField jTextField2;
    private javax.swing.JTextField jTextField3;
    // End of variables declaration//GEN-END:variables
    class paintListener implements Runnable{
        int hx,hy,hx2,hy2;
        Thread t;
        paintListener(){
            Thread t = new Thread(this);
            t.start();
        }
        public void run(){
            while(true){
                iconBroadcast();
                try{
                    t.sleep(10);
                }catch (Exception e) {}
            }
        }
        public void iconBroadcast(){
            int x = drawingPanel21.iconSX; int y = drawingPanel21.iconSY;
            String mesg = "i*"+x+":"+y+":"+drawingPanel21.selectedIcon;
            if(x!=0 && y!=0 && drawingPanel21.selectedIcon!=-1){
                drawingPanel21.iconSX = 0;
                drawingPanel21.iconSY = 0;
                drawingPanel21.selectedIcon=-1;
                for (int i=0; i<clients.size(); i++) {
                    out.println(mesg);
                    //ClientWorker sib = (ClientWorker)clients.get(i);
                    //sib.out.println(mesg);
                }
            }
        }
    }  
    class ClientHelper implements Runnable{
        String fromServer = "";
        String confirmedName = "";
        String myName;
        String serverIP;
        
        int pointX, pointY; //starting point for mouse, drag is then added on to line
        boolean kill = false;
        ClientHelper(String IP, String name){
            serverIP = IP;
            myName = name;
        }
        public void run(){
            try {
                kkSocket = new Socket(serverIP, 4433);
                out = new PrintWriter(kkSocket.getOutputStream(), true);
                in = new BufferedReader(new InputStreamReader(kkSocket.getInputStream()));
            } catch (UnknownHostException e) {
                jTextArea1.append("#ERROR# Couldnt connect to "+serverIP+".");
                //jTextArea1.setCaretPosition(jTextArea1.getText().length());
                kill = true; connected = false; jTextField2.setEditable(true);
            } catch (IOException e) {
                jTextArea1.append("#ERROR# Couldnt connect to "+serverIP+".");
                //jTextArea1.setCaretPosition(jTextArea1.getText().length());
                kill = true; connected = false; jTextField2.setEditable(true);
            }
            if(kill == false){
                out.println(myName);
                drawingPanel21.setName(myName);
                try {
                    while ((fromServer = in.readLine()) != null) {
                        if(confirmedName!=""){
                            jTextArea1.append(""+fromServer);
                            //jTextArea1.setCaretPosition(jTextArea1.getText().length());
                            break;
                        }
                        confirmedName = fromServer;
                        //Other client information such as other clients
                    }
                    while ((fromServer = in.readLine()) != null) {
                        parseIn(fromServer);
                    }
                }catch(IOException e){
                    jTextArea1.append("Lost Connection to Host ("+e.getMessage()+").");
                }catch(RuntimeException e){
                    jTextArea1.append("Lost Connection to Host ("+e.getMessage()+").");
                }
                //}catch(IllegalThreadStateException e){
                    //jTextArea1.append(""+fromServer);
                //}
            }
        }
        public void parseIn(String fromServer){
            try{
                String[] splitS = fromServer.split("\\*");
                if(splitS[0].equals("c")){ //its painting!
                    String split2[] = splitS[1].split(":");
                    int x,y,x2,y2;
                    x=0;y=0;
                    int hx=pointX,hy=pointY;
                    for (int z=0; z<split2.length;z+=3){
                        if(split2[z] != "" || split2[z] != null){
                            String split4[] = split2[z].split(",");

                            x = Integer.valueOf(split4[0]).intValue();
                            y = Integer.valueOf(split4[1]).intValue();

                            //x2 = Integer.valueOf(split4[2]).intValue();
                            //y2 = Integer.valueOf(split4[3]).intValue();
                            drawingPanel21.paintLine(x,y,hx,hy);
                            hx = x;
                            hy = y;
                        }
                    }
                    pointX = x;
                    pointY = y;
                }else if(splitS[0].equals("pp")){ //ew pointer location
                    String split2[] = splitS[1].split(":");
                    pointX = Integer.valueOf(split2[0]).intValue();
                    pointY = Integer.valueOf(split2[1]).intValue();
                }else if(splitS[0].equals("n")){ //ew client name! check if myname
                    if (splitS[1].equals(myName)){
                    }else{
                        addToClientList(splitS[1]);
                    }
                }else if(splitS[0].equals("typ")){ //typing
                    String split2[] = splitS[1].split(":");
                    int typing = Integer.valueOf(split2[1]).intValue();
                    updateStatus(split2[0], typing);
                }else if(splitS[0].equals("noc")){
                    if (splitS[1].equals("1")){
                        canType = false;
                        jTextArea1.append("<i>(Chat disabled.)");
                    }else{
                        canType = true;
                        jTextArea1.append("<i>(Chat enabled.)");
                    }
                }else if(splitS[0].equals("i")){
                    String split2[] = splitS[1].split(":");
                    int x = Integer.valueOf(split2[0]).intValue();
                    int y = Integer.valueOf(split2[1]).intValue();
                    int id = Integer.valueOf(split2[2]).intValue();

                    if (drawingPanel21.selectedIcon == id){
                    }else{
                        drawingPanel21.moveIcon(x,y,id);
                    }
                }else if(splitS[0].equals("q")){
                    String split2[] = splitS[1].split(":");
                    for (int i=0; i<split2.length; i++){
                        clients.add(split2[i]);
                        clientStatus.add("");
                    }
                    jList1.setListData(split2);
                    //jTextArea1.append(" "); THIS CAUSE PROBLEM AND FIXES
                    //jTextArea1.setCaretPosition(jTextArea1.getText().length());
                }else if (splitS[0].equals("p")){
                    String split2[] = splitS[1].split(":");
                    if(split2[0].equals("false")){
                        drawingPanel21.penColor = Color.BLACK;
                    }else{
                        drawingPanel21.penColor = Color.WHITE;
                    }
                    drawingPanel21.penSize = Integer.valueOf(split2[1]).intValue();
                }else if(splitS[0].equals("w")){
                    drawingPanel21.wipeGrid(Integer.valueOf(splitS[1]).intValue());
                }else if(splitS[0].equals("L")){
                    removeClient(splitS[1]);
                    jTextArea1.append(splitS[1]+" has left.");
                }else if(splitS[0].equals("res")){
                    String split2[] = splitS[1].split(":");
                    int xO = Integer.valueOf(split2[0]).intValue();
                    int yO = Integer.valueOf(split2[1]).intValue();
                    drawingPanel21.setCenterOffsets(xO,yO);
                }else if(splitS[0].equals("ic")){ //ICON ADD
                    String split2[] = splitS[1].split(":");
                    drawingPanel21.addIcon(Integer.valueOf(split2[2]).intValue(),Integer.valueOf(split2[3]).intValue(),split2[0],split2[1]);
                }else{
                    jTextArea1.append(fromServer);
                    //jTextArea1.setCaretPosition(jTextArea1.getText().length());
                }
            }catch(NumberFormatException e){
            }catch(RuntimeException e){}
        }
    }
}

